#pragma once
#include "requestor.hpp"
// 内部向外提供rpc调用的接口(同步,异步,回调)
namespace bitpr
{

    namespace client
    {

        class RpcCaller
        {
        public:
            using ptr = std::shared_ptr<RpcCaller>;
            using JsonAsyncResponse = std::future<Json::Value>;                    // 异步调用使用future类
            using JsonResponseCallback = std::function<void(const Json::Value &)>; // 回调

            RpcCaller(const Requestor::ptr &requestor):_requestor(requestor){}
            // requestor中的处理是针对BaseMessage进行处理的
            // 用于在rpccaller中针对结果的处理是针对 RpcResponse里边的result进行的
            // 实际上这个rpccaller才是上层接口
            bool call(const BaseConnection::ptr &conn, const std::string &method, const Json::Value &params, Json::Value &result)
            {
                DLOG("开始同步rpc调用...");
                //1.组织请求
                auto req_msg=MessageFactory::create<RpcRequest>();
                req_msg->setId(UUID::uuid());
                req_msg->setMType(MType::REQ_RPC);
                req_msg->setMethod(method);
                req_msg->setParams(params);
                BaseMessage::ptr rsp_msg;
                //2发送请求 调用这个requestor.hpp,三个参数链接状态,请求信息,响应信息
                bool ret =_requestor->send(conn,std::dynamic_pointer_cast<BaseMessage>(req_msg),rsp_msg);
                if(ret==false){
                    ELOG("请求同步rpc失败");
                    return false;
                }
                DLOG("收到响应,进行解析,获取结果");
                //3等待响应
                auto rpc_rsp_msg=std::dynamic_pointer_cast<RpcResponse>(rsp_msg);//获取这个响应
                if(!rpc_rsp_msg)
                {
                    ELOG("rpc响应,向下类型转换失败");
                    return false;
                }
                if(rpc_rsp_msg->rcode()!=RCode::RCODE_OK){
                    ELOG("rpc请求出错%s",errReason(rpc_rsp_msg->rcode()).c_str());//打出错误响应码;
                    return false;
                }
                result=rpc_rsp_msg->result();
                DLOG("结果设置完毕");
                return true;



            }
            //异步回调函数
            bool call(const BaseConnection::ptr &conn, const std::string &method,
                      const Json::Value &params, JsonAsyncResponse &result)
            {
                //向这个服务器发送这个异步回调请求,设置回调函数,回调函数会传入一个promise对象,在回调函数里面promise设置数据
                  auto req_msg=MessageFactory::create<RpcRequest>();
                req_msg->setId(UUID::uuid());
                req_msg->setMType(MType::REQ_RPC);
                req_msg->setMethod(method);
                req_msg->setParams(params);
                //2封装请求
                //实例化
                auto json_promise=std::make_shared<std::promise<Json::Value>>();//避免作用域问题
                //获取联系
                result=json_promise->get_future();
                //调用这个requestot里面的req_promise进程的函数
                //第一个参数json_promise ,所以cb(参数)是callback的第二个参数
                Requestor::RequestCallback cb =std::bind(&RpcCaller::Callback,
                this,json_promise,std::placeholders::_1);
                bool ret=_requestor->send(conn,std::dynamic_pointer_cast<BaseMessage>(req_msg),cb);
                if(ret=false)
                {
                    ELOG("异步请求失败");
                    return false;
                }
                return true;

            }
            bool call(const BaseConnection::ptr &conn, const std::string &method,
                      const Json::Value &params, const JsonResponseCallback &cb)
            {
                auto req_msg = MessageFactory::create<RpcRequest>();
                    req_msg->setId(UUID::uuid());
                    req_msg->setMType(MType::REQ_RPC);
                    req_msg->setMethod(method);
                    req_msg->setParams(params);
                Requestor::RequestCallback req_cb=std::bind(&RpcCaller::Callback1,this,cb,std::placeholders::_1);
               
                bool ret=_requestor->send(conn,std::dynamic_pointer_cast<BaseMessage>(req_msg),req_cb);
                if(ret==false){
                    ELOG("回调rpc失败");
                    return false;
                }
                return true; 

            }

        private:
            Requestor::ptr _requestor;
            //回调函数
            void Callback1(const JsonResponseCallback &cb ,const BaseMessage::ptr &msg){

                 auto rpc_rsp_msg = std::dynamic_pointer_cast<RpcResponse>(msg);
                    if (!rpc_rsp_msg) {
                        ELOG("rpc响应，向下类型转换失败！");
                        return ;
                    }
                    if (rpc_rsp_msg->rcode() != RCode::RCODE_OK) {
                        ELOG("rpc回调请求出错：%s", errReason(rpc_rsp_msg->rcode()).c_str());
                        return ;
                    }
                    cb(rpc_rsp_msg->result());
            }
            //异步封装函数
            void Callback(std::shared_ptr<std::promise<Json::Value>> result,const BaseMessage::ptr &msg){

                auto rpc_rsp_msg=std::dynamic_pointer_cast<RpcResponse>(msg);
                if(!rpc_rsp_msg){
                    ELOG("rpc响应,向下类型装换失败");
                }
                 if (rpc_rsp_msg->rcode() != RCode::RCODE_OK) {
                        ELOG("rpc异步请求出错：%s", errReason(rpc_rsp_msg->rcode()).c_str());
                        return ;
                    }
                    result->set_value(rpc_rsp_msg->result());//异步最关键的步骤
                }

            
        };


    }
}